
let {mat4,vec3} = require('gl-matrix');


let tmpv1 = vec3.create();
let tmpv2 = vec3.create();
let tmpv3 = vec3.create();
let tmpMat1 = mat4.create();

class Camera{

    fovy = 60;
    near = 0.1;
    far = 1000;

    constructor(pos,
                target = vec3.fromValues(0,0,0),
                up = vec3.fromValues(0,1,0)) {
        this.projMatrix = mat4.create();
        this.viewMatrix = mat4.create();

        this.position = vec3.fromValues(pos[0],pos[1],pos[2]);
        this.target = vec3.fromValues(target[0],target[1],target[2]);;
        this.up = vec3.fromValues(up[0],up[1],up[2]);

        //  使用几个角度来表示相机
    }

    calProjMatrix(width,height){
        mat4.perspective(
            this.projMatrix,
            this.fovy * Math.PI / 180.0,
            width/height,
            this.near,
            this.far
            );
    }

    calViewMatrix(){
        mat4.lookAt(this.viewMatrix,this.position,this.target,this.up);
    }

    slide_left_to_right(degress){

        // camera -z
        let dir = vec3.sub(tmpv1,this.target,this.position);
        let len = vec3.length(dir);

        let rad = degress * Math.PI / 180;
        mat4.fromYRotation(tmpMat1,rad);
        vec3.transformMat4(dir,dir,tmpMat1);
        vec3.normalize(dir,dir);
        vec3.scale(dir,dir,-len);
        vec3.add(this.position,this.target,dir);
    }

    slide_down_to_up(degress){

        // camera -z
        let dir = vec3.sub(tmpv1,this.target,this.position);
        let left = vec3.cross(tmpv2,dir,this.up);
        vec3.normalize(left,left);

        let len = vec3.length(dir);
        let rad = degress * Math.PI / 180;

        mat4.fromRotation(tmpMat1,rad,left);
        vec3.transformMat4(dir,dir,tmpMat1);
        vec3.normalize(dir,dir);

        // 防止出现万向节锁
        if (Math.abs(dir[1] ) > 0.8){
            return;
        }

        vec3.scale(dir,dir,-len);
        vec3.add(this.position,this.target,dir);
    }

    // 移动
    translateX(value){
        // camera -z
        let dir = vec3.sub(tmpv1,this.target,this.position);
        let left = vec3.cross(tmpv2,dir,this.up);
        vec3.normalize(left,left);
        vec3.scale(left,left,value);
        vec3.add(this.target,this.target,left);
        vec3.add(this.position,this.position,left);
    }

    translateZ(value,fly = false){

        // camera -z
        let dir = vec3.sub(tmpv1,this.target,this.position);
        vec3.normalize(dir,dir);
        vec3.scale(dir,dir,value);

        if (!fly){
            dir[1] = 0;
        }

        vec3.add(this.target,this.target,dir);
        vec3.add(this.position,this.position,dir);
    }


}

module.exports = Camera;
